/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view.contents.transition;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.Timer;

import view.contents.ImageTransitioner;

/**
 * 
 * @author Yang Wang <yang@digitalmenubox.com>
 */
public class GravityBouncer implements ImageTransition, ActionListener {

	private ImageTransitioner box;
	private BufferedImage bi;
	private Graphics2D g;
	private Timer timer;
	private boolean finished;
	private int y = 0;
	private double t = 0;
	private double gravity = 9.81d;
	double accTime = 0;
	private int bounceLimit = 5;
	private int numBounces = 0;
	private double bounceRatio = 0.3;
	private int bounceHeight;
	private boolean isDropping = false;

	public GravityBouncer(ImageTransitioner box) {
		this.box = box;
		bi = new BufferedImage(box.getWidth(), box.getHeight(), BufferedImage.TYPE_INT_ARGB);
		g = (Graphics2D) bi.getGraphics();
		y = (-1) * box.getHeight();
		bounceHeight = (int) (-box.getHeight() * bounceRatio);
	}

	@Override
	public void animate(ImageTransitioner box, int time) {
		ImageTransition transition = new GravityDropDown(box);
		transition.animate(box, time);

		timer = new Timer(20, this);
		timer.setDelay(20);
		timer.start();
		// make the timer wait until the animation has been finished
		synchronized (timer) {
			try {
				timer.wait();
			} catch (InterruptedException ex) {
				Logger.getLogger(SlideDown.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}

	public static void main(String[] args) {
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		g.setBackground(new Color(255, 255, 255, 0));
		g.clearRect(0, 0, box.getWidth(), box.getHeight());

		if (numBounces < bounceLimit || y != 0) {
			if (isDropping) {
				y = Math.min(0, bounceHeight + (int) (gravity / 2 * Math.pow(t / 1000, 2)));
				t = t + 700;
			} else {
				// move up
				y = Math.max(bounceHeight, bounceHeight - (int) (gravity / 2 * Math.pow(t / 1000, 2)));
				t = t + 700;
			}

			if (y <= bounceHeight) {
				// if bounceHeight is reached, make the ball drop
				isDropping = true;
				t = 700;
			}
			if (y >= 0) {
				// if height reaches 0, increment numBounces
				bounceHeight = (int) (bounceHeight * bounceRatio);
				numBounces++;
				isDropping = false;
				t = 700;
			}
			g.drawImage(box.getOverlayImage(), 0, y, null);
			box.setTransitionImage(bi);
			System.out.println(y + " " + numBounces);
		} else {
			synchronized (timer) {
				timer.stop();
				timer.notifyAll();
				this.unsetVariables();
			}
		}
	}

	private void unsetVariables() {
		this.box = null;
		bi = null;
		g = null;
	}

	class BounceActionListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
		}
	}
}
